package org.aplikator.client.local.widgets;

import com.github.gwtbootstrap.client.ui.*;
import com.github.gwtbootstrap.client.ui.constants.IconType;
import com.github.gwtbootstrap.client.ui.resources.ButtonSize;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.ui.FlowPanel;

import org.aplikator.client.local.Aplikator;
import org.aplikator.client.shared.data.Operation;
import org.aplikator.client.shared.data.PrimaryKey;
import org.aplikator.client.shared.data.Record;
import org.aplikator.client.shared.data.RecordContainer;
import org.aplikator.client.shared.descriptor.PropertyDTO;
import org.aplikator.client.shared.descriptor.RecordsPageDTO;
import org.aplikator.client.shared.descriptor.ViewDTO;
import org.aplikator.client.shared.rpc.ParameterWrapperGetPage;
import org.jboss.errai.common.client.api.RemoteCallback;

import java.util.ArrayList;
import java.util.List;

public class RepeatedFormWidget extends ContainerFieldBase implements NestedCollectionWidget {

    public interface RepeatedFormWidgetResources extends ClientBundle {
        public static final RepeatedFormWidgetResources INSTANCE = GWT.create(RepeatedFormWidgetResources.class);

        @Source("images/icons/plus16.png")
        ImageResource create();

        @Source("images/icons/minus16.png")
        ImageResource delete();

        @Source("RepeatedFormWidget.css")
        public RepeatedFormWidgetCss css();
    }

    public interface RepeatedFormWidgetCss extends CssResource {
        public String repeatedForm();

        public String repeatedFormFirst();
    }

    static {
        RepeatedFormWidgetResources.INSTANCE.css().ensureInjected();
    }

    private List<FormWidget> nestedForms = new ArrayList<FormWidget>();



    private Button buttonCreate;

    private ViewDTO view;
    private List<Record> pageData;

    private PrimaryKey ownerPrimaryKey;

    private PropertyDTO ownerProperty;

    private HasFields ownerForm;

    RecordContainer recordContainer;

    private boolean enabled = true;

    public RepeatedFormWidget(ViewDTO view, PropertyDTO ownerProperty, HasFields ownerForm, boolean enabled) {
        super();
        this.view = view;
        this.ownerProperty = ownerProperty;
        this.ownerForm = ownerForm;
        this.enabled = enabled;
        Well well = new Well();
        wrapper = new ControlGroup();
        this.label = new ControlLabel(ownerProperty.getLocalizedName());
        this.controls = new Controls();
        initWidget(wrapper);
        controls.add(well);
        wrapper.add(this.label);
        wrapper.add(this.controls);

        // forms container
        dataPanel = new Column(12);
        //FluidRow dpWrapper = new FluidRow();
        //dpWrapper.add(dataPanel);

        buttonCreate = new Button("", IconType.PLUS);
        buttonCreate.setSize(ButtonSize.MINI);

        buttonCreate.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                RepeatedFormWidget.this.buttonCreateClicked();
            }
        });

        buttonCreate.setEnabled(enabled);
        well.add(dataPanel);
        well.add(buttonCreate);
        //navigationPanel.setStyleName(ContainerFieldResources.INSTANCE.css().contentsHeader());
        //basePanel.setStyleName(ContainerFieldResources.INSTANCE.css().contentsFrame());
        //dataPanel.setStyleName(ContainerFieldResources.INSTANCE.css().contentsHolder());

    }

    private void loadData() {
        dataPanel.clear();
        dataPanel.add(new LoadingLabel());
        Aplikator.aplikatorService.call( new RemoteCallback<RecordsPageDTO>() {
            @Override
            public void callback(RecordsPageDTO resp) {
                RepeatedFormWidget.this.pageData = resp.getRecords();
                redrawPage();
            }
        }).getPage(new ParameterWrapperGetPage(view.getId(), ownerProperty), (ownerPrimaryKey==null)?null:ownerPrimaryKey.getSerializationString(), 0, -1);

    }

    private void redrawPage() {
        dataPanel.clear();
        nestedForms.clear();
        for (int i = 1; i <= pageData.size(); i++) {
            FormWidget form = new FormWidget(this.view, null, ownerForm);
            form.displayRecord(pageData.get(i - 1).getPrimaryKey(), recordContainer);
            addForm(form);
        }

    }

    private void buttonCreateClicked() {
        FormWidget form = new FormWidget(this.view, null, ownerForm);
        form.addRecord(recordContainer, ownerProperty, ownerPrimaryKey, null);
        pageData.add(form.getOriginal());
        addForm(form);
        ownerForm.setDirty(true);
    }

    private void buttonDeleteClicked(FormWidget form) {
        for (int i = 0; i < nestedForms.size(); i++) {
            if (form == nestedForms.get(i)) {
                nestedForms.remove(i);
                ((FlowPanel) dataPanel).remove(i);
                recordContainer.addRecord(view, pageData.get(i), null, Operation.DELETE);
                pageData.remove(i);
                ownerForm.setDirty(true);
                break;
            }
        }
    }

    private void addForm(final FormWidget form) {
        nestedForms.add(form);
        Button buttonDelete = new Button("", IconType.MINUS);
        buttonDelete.setSize(ButtonSize.MINI);
        buttonDelete.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                RepeatedFormWidget.this.buttonDeleteClicked(form);
            }
        });
        buttonDelete.setEnabled(enabled);
        form.setEnabled(enabled);
        Column formHolder = new Column(11,form);
        Column buttonHolder = new Column(1,buttonDelete);
        FluidRow holder = new FluidRow();

        // holder.setWidth("100%");
        // holder.setHeight("auto");

        /*if (((FlowPanel) dataPanel).getWidgetCount() == 0) {
            holder.setStylePrimaryName(RepeatedFormWidgetResources.INSTANCE.css().repeatedFormFirst());
        } else {
            holder.setStylePrimaryName(RepeatedFormWidgetResources.INSTANCE.css().repeatedForm());
        } */
        holder.addStyleName(RepeatedFormWidgetResources.INSTANCE.css().repeatedForm());
        holder.add(buttonHolder);
        holder.add(formHolder);

        dataPanel.add(holder);
    }

    public PrimaryKey getOwnerPrimaryKey() {
        return ownerPrimaryKey;
    }

    public void setOwnerPrimaryKey(PrimaryKey value) {
        ownerPrimaryKey = value;
        loadData();
    }

    public void setRecordContainer(RecordContainer recordContainer) {
        this.recordContainer = recordContainer;
    }

    public void save() {
        for (FormWidget nestedForm : nestedForms) {
            nestedForm.save();
        }
    }

    public void setDirty(boolean dirty) {
        for (FormWidget nestedForm : nestedForms) {
            nestedForm.setNestedDirty(dirty);
        }
    }

}
